import QtQuick 2.0
import FileIO 1.0
import Process 1.0

Item {
    id: hdiffInstaller

    signal finished()
    signal error()

    property string outputDir

    readonly property alias isRunning: process.isRunning
    property var progress

    readonly property string hdiffFilesPath: outputDir + "hdifffiles.txt"
    property var filesToPatch: []
    property int totalFilesCount: 0


    Process {
        id: process

        property string hdiff
        property string lastOutput
        property string binPath: applicationDirPath + "/tools/"

        property string remoteFile
        property string sourceFile
        property string newFile
        property string patchFile

        workingDirectory: outputDir

        onFinished: {
            console.log("hpatchz exit code: " + code)

            if (code === 0) {
                handleSuccess()
            } else {
                handleError()
            }
        }

        onOutputRead: {
            lastOutput = output
        }

        function install(file) {
            ui.log("Updating " + file)

            let patchedCount = totalFilesCount - filesToPatch.length
            progress = {
                value: patchedCount,
                total: totalFilesCount,
            }

            remoteFile = file
            sourceFile = outputDir + file
            newFile = sourceFile + ".new"
            patchFile = sourceFile + ".hdiff"

            FileIO.removeFile(newFile)
            process.start(binPath + "hpatchz", [sourceFile, patchFile, newFile])
        }

        function handleSuccess() {
            FileIO.removeFile(sourceFile)
            FileIO.removeFile(patchFile)
            FileIO.rename(newFile, sourceFile)
            installNextPatch()
        }

        function handleError() {
            if (integrityCheck.check(remoteFile)) {
                ui.log(remoteFile + qsTr(" is already patched"))
                // file was already patched ingame, skipping
                FileIO.removeFile(patchFile)
                installNextPatch()
                return
            }

            ui.log(lastOutput)
            hdiffInstaller.error()
        }
    }


    function isInstallNeeded() {
        return FileIO.isFileExists(hdiffFilesPath)
    }

    function installAll() {
        ui.log("")
        ui.log(qsTr("Installing HDiff patches..."))

        let hdiffs = FileIO.readTextFile(hdiffFilesPath).split("\n")

        let files = []
        for (let hdiff of hdiffs) {
            if (hdiff.trim() === "")
                continue

            try {
                let json = JSON.parse(hdiff)
                let baseName = outputDir + json.remoteName
                if (FileIO.isFileExists(baseName + ".hdiff")) {
                    files.push(json.remoteName)
                }
            } catch(e) {
                ui.log(file + ": " + e)
            }
        }

        installByList(files)
    }

    function installByList(files) {
        filesToPatch = files
        totalFilesCount = files.length

        installNextPatch()
    }

    function installNextPatch() {
        let file = filesToPatch.shift()
        if (!file) {
            ui.log(qsTr("HDiff patches have been installed."))
            FileIO.removeFile(hdiffFilesPath)
            finished()
            return
        }

        process.install(file)
    }

    function cancel() {
        process.terminate()
    }
}
